//:C15:StaticHierarchyNavigation.cpp
// Navgating class hierarchies with static_cast
#include <iostream>
#include <typeinfo>
using namespace std;

class Shape
{
    public:
        virtual ~Shape(){};
};

class Circle : public Shape{};
class Square : public Shape{};
class Other : public Shape{};

int main(void)
{
    Circle c;
    Shape *s = &c;    // Upcast: normal and OK
    // More explicit but unnecessary:
    s = static_cast<Shape*>(&c);
    // (Since upcasting is such a safe and common
    // operation, the cast becomes cluttering)
    Circle *cp = 0; 
    Square *sp = 0;
    // Static Navgation of class hierarchies
    // requires extra type information: 
    if(typeid(s) == typeid(cp)) 
    {   // C++ RTTI
        cp = static_cast<Circle*>(s);
    }
    if(typeid(s) == typeid(sp)) 
    {   // C++ RTTI
        sp = static_cast<Square*>(s);
    }
    if(cp != 0)
    {
        cout << "It's a circle!" << endl;
    }
    if(sp != 0)
    {
        cout << "It's a square!" << endl;
    }
    // Static navigation is ONLY an efficiency hack:
    // dynamic_cast is always safer. However:
    // Other* op = static_cast<Other*>(s);
    // Conveniently gives an error message, while
    Other *op2 = (Other*)s;
    // does not
}
